#coding=utf-8
'''
# @Name:user_resource
# @author:mysouil
# @Description:
# @DATE:2022/9/21 23:49
# @Modified By:
'''
import re
import random
from flask_restful import Resource
from flask import current_app,request,g
from comment.utils.SendMessage import send_message
from comment.utils.limit import limiter,get_remote_address
from comment.utils.shopping_redis import redis_client
from flask_restful.reqparse import RequestParser
from comment.utils import tools
from comment.models.user import User
from comment.models import db
from comment.utils.token_pyjwt import generate_token
from comment.utils.decorates import login_required

class Shopping_User(Resource):
    
    method_decorators = {
        'get':[login_required],
        'post': [login_required]
    }
    
    def get(self):
        # current_app.logger.debug('hello')
        # current_app.logger.info('123')
        return {'get':'get请求'}
    
    def post(self):
        return {'post':'post请求'}
    
    def put(self):
        return {'put':'put请求'}

   
class User_MSM(Resource):
    '''
    发送短信验证码
    '''
    
    decorators = [
        # 三个参数 参数1：限流的频率 参数2：key_func(根据什么来限制) 参数3：超出限制之后的提示信息
        limiter.limit("1/minute",key_func=lambda :request.args['phone'],error_message='请求频率太快，请1分钟后，再试'),
        limiter.limit("30/hour", key_func=get_remote_address, error_message='请求频率太快，请30分钟后，再试')
    ]
    
    def get(self):
        phone = request.args.get('phone').strip()
        
        # 验证手机号是否合法
        if not re.match('^1[3789]\d{9}$',phone):
            return {'statusCode':'400','message':'手机号码填写错误'},400
        
        code = ''
        for i in random.choices(range(1,10),k=6):
            code+=str(i)
        print('验证码为：',code)

        # 将短信验证码存入redis
        flag = 'is_%s'%phone
        redis_client.setex(flag,60,code)
        
        # 发送短信验证码，并接收返回的json数据
        # data = send_message(phone,code)
        # 测试直接通过数据，不需要真实发送短信验证码
        data = {'statusCode':'000000'}
        
        if data.get('statusCode')=='000000':
            data['phone'] = phone
            print("发送成功")
        else:
            print("发送失败")
        return data

class AuthorizationCodeResource(Resource):
    
    '''
        提交手机号和验证码，开始验证
    '''
    
    def post(self):
        rp = RequestParser()
        
        # 获取手机号并校验
        rp.add_argument('phone',type=tools.mobile,required=True,help='phone is a not can use params')
        # 获取验证码并校验(4到6位的验证码)
        rp.add_argument('code',type=tools.regex('^\d{4,6}$'),required=True,help='code is a not can use params')
        
        args = rp.parse_args()
        
        phone = args['phone']
        code = args['code']
        
        # 从redis数据库中得到保存的验证码
        key = 'is_%s'%phone
        
        try:
            value = redis_client.get(key).decode()
        except Exception as e:
            current_app.logger.error(e)
            return {'statusCode':'400','message':'参数前后验证不一致'},400
        
        if value and value==code:
            return {'statusCode':'200'},200
        else:
            return {'statusCode': '400', 'message': 'This is a valid code.'}, 400
        
        
class RegisterUserResource(Resource):
    '''
    填写账号信息，完成用户的注册
    '''
    
    def post(self):
        rp = RequestParser()
        rp.add_argument('phone', type=tools.mobile, required=True, help='phone is a not can use params')
        rp.add_argument('username',type=tools.regex('^\w{6,18}'), required=True, help='username is a not can use params')
        rp.add_argument('password',type=tools.regex('^\w{6,18}'), required=True, help='password is a not can use params')
        rp.add_argument('email', type=tools.check_email, required=True, help='email is a not can use params')
        
        args = rp.parse_args()
        
        phone = args['phone']
        username = args['username']
        password = args['password']
        email = args['email']
        
        # 验证用户名是否唯一
        user = User.query.filter(User.username==username).first()
        if user:
            current_app.logger.info('{}-->用户名已经存在')
            return {'statusCode':'400','message':'用户名已经存在'},400
        
        user = User(username=username,pwd=password,email=email,phone=phone,status=0)
        db.session.add(user)
        db.session.commit()
        return {'statusCode': '200'}, 200
    

class LoginUserResource(Resource):
    '''
    登陆请求
    '''
    def post(self):
        username = request.form.get('username')
        password = request.form.get('password')
        
        if not all([username,password]) or not re.match('^\w{6,18}',username) or not re.match('^\w{6,18}',password):
            return {'statusCode':'402','message': '用户名或密码不符合规范'},402
        
        user = User.query.filter(User.username==username).first()
        if user:
            if user.check_password(password):
                # 必须把登陆成功后的用户id得到token，token返回前端
                token = generate_token(user.id)
                return {'token':token,'username':username}
        
        return {'statusCode':'400','message':'用户名或密码有误'},400
    
class IsExistPhoneResource(Resource):
    '''
    判断手机号是否存在
    '''
    def post(self):
        phone = request.form.get('phone')
        
        user = User.query.filter(User.phone==phone).first()
        if user: # 表示手机号已被注册
            return {'isExist':True,'message':'手机号已被注册','statusCode':'203'}
        
        return {'isExist':False}
    
    
class UserLoginOutResource(Resource):
    '''
    退出登录
    '''
    
    def post(self):
        if g.user_id:
            del g.user_id
        
        return {'msg':'退出登录'}